/*
 带虚函数表的多态实现示例
 
 本示例展示了如何使用虚函数表在C语言中实现完整的多态特性：
 1. 定义虚函数表结构
 2. 为每个类创建独立的虚函数表
 3. 通过虚函数表实现动态绑定
 
 继承结构：
   Shape (基类)
    |
    +-- Circle (子类)
    +-- Rectangle (子类)
 */

#include <stdio.h>
#include <stdlib.h>

// ===== 基类: Shape =====
// 定义虚函数表结构
typedef struct {
    void (*draw)(void*);
    float (*area)(void*);
} ShapeVTable;

typedef struct {
    const ShapeVTable* vtable;  // 虚函数表指针
    int x, y;                   // 位置属性
} Shape;

// Shape的虚函数实现
void shape_draw(void* self) {
    printf("Drawing generic shape at (%d, %d)\n", ((Shape*)self)->x, ((Shape*)self)->y);
}

float shape_area(void* self) {
    printf("Area of generic shape is undefined\n");
    return 0.0f;
}

// 静态虚函数表实例（全局唯一）
static const ShapeVTable shape_vtable = {
    .draw = shape_draw,
    .area = shape_area
};

// 初始化Shape对象
void shape_init(Shape* shape, int x, int y) {
    shape->vtable = &shape_vtable;
    shape->x = x;
    shape->y = y;
}

// ===== 子类: Circle =====
typedef struct {
    Shape base;                 // 继承Shape
    int radius;                 // 子类特有的属性
} Circle;

// Circle的虚函数实现
void circle_draw(void* self) {
    Circle* circle = (Circle*)self;
    printf("Drawing circle at (%d, %d) with radius %d\n", 
           circle->base.x, circle->base.y, circle->radius);
}

float circle_area(void* self) {
    Circle* circle = (Circle*)self;
    return 3.14f * circle->radius * circle->radius;
}

// Circle的虚函数表
static const ShapeVTable circle_vtable = {
    .draw = circle_draw,
    .area = circle_area
};

// 初始化Circle对象
void circle_init(Circle* circle, int x, int y, int radius) {
    // 首先初始化父类部分
    shape_init(&circle->base, x, y);
    
    // 然后设置子类的虚函数表
    circle->base.vtable = &circle_vtable;
    
    // 最后设置子类特有的属性
    circle->radius = radius;
}

// ===== 子类: Rectangle =====
typedef struct {
    Shape base;                 // 继承Shape
    int width, height;          // 子类特有的属性
} Rectangle;

// Rectangle的虚函数实现
void rectangle_draw(void* self) {
    Rectangle* rect = (Rectangle*)self;
    printf("Drawing rectangle at (%d, %d) with width %d and height %d\n", 
           rect->base.x, rect->base.y, rect->width, rect->height);
}

float rectangle_area(void* self) {
    Rectangle* rect = (Rectangle*)self;
    return (float)rect->width * rect->height;
}

// Rectangle的虚函数表
static const ShapeVTable rectangle_vtable = {
    .draw = rectangle_draw,
    .area = rectangle_area
};

// 初始化Rectangle对象
void rectangle_init(Rectangle* rect, int x, int y, int width, int height) {
    shape_init(&rect->base, x, y);
    rect->base.vtable = &rectangle_vtable;
    rect->width = width;
    rect->height = height;
}

// ===== 类型转换函数 =====
Shape* circle_to_shape(Circle* circle) { return &circle->base; }
Shape* rectangle_to_shape(Rectangle* rect) { return &rect->base; }

// ===== 测试代码 =====
int main() {
    // 创建对象
    Circle circle;
    circle_init(&circle, 10, 20, 5);
    
    Rectangle rect;
    rectangle_init(&rect, 30, 40, 10, 20);
    
    // 通过基类指针调用方法（多态）
    Shape* shapes[2] = {
        circle_to_shape(&circle),
        rectangle_to_shape(&rect)
    };
    
    // 遍历并调用方法
    for (int i = 0; i < 2; i++) {
        shapes[i]->vtable->draw(shapes[i]);
        printf("Area: %.2f\n", shapes[i]->vtable->area(shapes[i]));
        printf("----------------\n");
    }
    
    return 0;
}